home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / Dots & Pixels / sources / C_randomizer.c < prev    next >
Text File  |  1995-09-29  |  5KB  |  181 lines

  1.  
  2. #include "C_randomizer.h"
  3.  
  4. static int seed_24_index = 24;
  5. static int seed_55_index =  0;
  6.  
  7. static unsigned long randomizer_theseeds[ 55] =
  8. {
  9.     1702803237, 3609857174, 1517566982, 1918061247, 1368775034,
  10.     3807181130,   66927828, 2508648394,  684483038, 1648047133,
  11.     2967841185,  252797108, 3864844816,  702424509,  683206901,
  12.     2289495513, 2594779536, 2502673239, 1159517122, 1677091079,
  13.     1260145853, 3188486680, 1282157716,  324433576, 1739387166,
  14.     3682410224, 4045723142, 2846836006, 3635585791,   11832984,
  15.     1985903735, 2287482506, 3383904320, 1140795862, 4220888830,
  16.     1317632102, 2580653160, 2614413823,  912417690, 3804890613,
  17.     1308492288,  652233149, 1450246829, 1664200832, 2764283166,
  18.     3236486674, 2592511403, 2283325954, 1972937535, 2802416540,
  19.     1405232398, 4064630287, 1580719194, 4053978138,   31904141,
  20. };
  21.  
  22. unsigned long randomizer_step( void)
  23. {
  24.     /*
  25.     // Note: copying the indices to temporary variables makes the
  26.     // code generated by THINK C shorter (and presumably faster)
  27.     */
  28.     int seed_24_copy = seed_24_index;
  29.     int seed_55_copy = seed_55_index;
  30.     /*
  31.     // We don't care for overflow here;we want to do modular arithmetic!
  32.     */
  33.     const unsigned long new_value =
  34.         randomizer_theseeds[ seed_24_copy] + randomizer_theseeds[ seed_55_copy];
  35.  
  36.     randomizer_theseeds[ seed_55_copy] = new_value;
  37.     /*
  38.     // If seed_24 has to be reset we are sure that seed_55 has not to be reset,
  39.     // so we do not have to check for that in 1 in every 55 cases.
  40.     */
  41.     if( seed_24_copy == 0)
  42.     {
  43.         seed_24_copy = 54;
  44.         seed_55_copy -= 1;
  45.     } else {
  46.         seed_24_copy -= 1;
  47.  
  48.         if( seed_55_copy == 0)
  49.         {
  50.             seed_55_copy = 54;
  51.         } else {
  52.             seed_55_copy -= 1;
  53.         }
  54.     }
  55.     /*
  56.     // Finally copy our temporary copies back to the static ones
  57.     */
  58.     seed_24_index = seed_24_copy;
  59.     seed_55_index = seed_55_copy;
  60.     return new_value;
  61. }
  62.  
  63. void randomizer_fill( unsigned long *start, long numSteps)
  64. {
  65.     /*
  66.     // Note: copying the indices to temporary variables makes the
  67.     // code generated by THINK C shorter (and presumably faster)
  68.     */
  69.     int seed_24_copy = seed_24_index;
  70.     int seed_55_copy = seed_55_index;
  71.     int steps_to_go  = numSteps;
  72.     /*
  73.     // We code for speed, using some ugly C hacks
  74.     */
  75.     do
  76.     {
  77.         /*
  78.         // We don't care for overflow here;we want to do modular arithmetic!
  79.         */
  80.         const unsigned long new_value = randomizer_theseeds[ seed_24_copy]
  81.                                         + randomizer_theseeds[ seed_55_copy];
  82.     
  83.         *start++ = randomizer_theseeds[ seed_55_copy] = new_value;
  84.         /*
  85.         // If seed_24 has to be reset we are sure that seed_55 has not to be
  86.         // reset, so we do not have to check for that in 1 in every 55 cases.
  87.         */
  88.         if( seed_24_copy == 0)
  89.         {
  90.             seed_24_copy = 54;
  91.             seed_55_copy -= 1;
  92.         } else {
  93.             seed_24_copy -= 1;
  94.     
  95.             if( seed_55_copy == 0)
  96.             {
  97.                 seed_55_copy = 54;
  98.             } else {
  99.                 seed_55_copy -= 1;
  100.             }
  101.         }
  102.         steps_to_go -= 1;
  103.     } while( steps_to_go != 0);
  104.     /*
  105.     // Finally copy our temporary copies back to the static ones
  106.     */
  107.     seed_24_index = seed_24_copy;
  108.     seed_55_index = seed_55_copy;
  109. }
  110.  
  111. double randomizer_a_double( void)
  112. {
  113.     const int grain = 10000000;
  114.     int newvalue = randomizer_an_int( grain + 1);
  115.     /*
  116.     // newvalue is in the [0, grain] range now, so division by grain
  117.     // brings it in the [0, 1] range, multiplication by max_value
  118.     // brings it in the requested range. To ensure that the result
  119.     // won't get bigger than 'max_value' or less than zero we handle
  120.     // the two extreme cases separately. Rounding errors for the other
  121.     // cases will not lead to these errors (unless grain is very big,
  122.     // of course). We also don't check whether 'max_value > 0.0'
  123.     // and/or 'grain > 1', but what the heck...
  124.     */
  125.     double result;
  126.  
  127.     if( newvalue == 0)
  128.     {
  129.          result = 0.0;
  130.     } else if( newvalue == grain) {
  131.         result = 1.0;
  132.     } else {
  133.         result = (double)newvalue / grain;
  134.     }
  135.     return result;
  136. }
  137.  
  138. void randomizer_reseed( unsigned long seed)
  139. {
  140.     unsigned long newseeds[ 55];
  141.     int i;
  142.     for( i = 0; i < 55; i++)
  143.     {
  144.         newseeds[ i] += randomizer_step() + seed;
  145.     }
  146.     /*
  147.     // Note: if seed is even we can be sure that not all newseeds are even
  148.     // since step() cannot return 55 even numbers in a row.
  149.     // If seed is odd, however, we have to make sure
  150.     // (step() can return 55 odd numbers in a row).
  151.     */
  152.     if( seed & 1)
  153.     {
  154.         int all_seeds_are_even = 1;
  155.         for( i = 0; i < 55; i++)
  156.         {
  157.             if( newseeds[ i] & 1)
  158.             {
  159.                 all_seeds_are_even = 0;
  160.                 break;
  161.             }
  162.         }
  163.         if( all_seeds_are_even)
  164.         {
  165.             /*
  166.             // calling randomizer_an_int does not return a uniformly
  167.             // distributed random integer here, but what the heck...
  168.             */
  169.             const int one_to_make_odd = randomizer_an_int( 55);
  170.             /*
  171.             // we know that the seed is even, so addition of 1 makes it odd
  172.             */
  173.             newseeds[ one_to_make_odd] += 1;
  174.         }
  175.     }
  176.     for( i = 0; i < 55; i++)
  177.     {
  178.         randomizer_theseeds[ i] = newseeds[ i];
  179.     }
  180. }
  181.